package com.iye.puretennis.custom;

import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import com.iye.puretennis.R;
import com.iye.puretennis.activity.MainTabsActivity;
import com.iye.puretennis.domain.*;
import com.iye.puretennis.fragment.TabFragment;
import com.iye.puretennis.helper.Constant;
import com.iye.puretennis.helper.RemoteUrlCollections;
import com.iye.puretennis.helper.ServerAccessHelper;
import com.iye.puretennis.helper.Session;
import com.iye.puretennis.utils.LocationUtils;
import com.iye.puretennis.utils.StringUtils;
import org.apache.http.entity.StringEntity;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: jing wu
 * Date: 2014/12/10
 * Time: 11:42
 */
public class UserInfoFragment extends TabFragment {

    private String userGuid;

    private UserInfo userInfo;

    private ImageButton inviteButton;

    public static final String TAG = "user_info";

    private ChatMessageWebSocket webSocketClient;

    private EditText messageEditText;

    private ListView messagesView;

    private ChatMessageAdapter messageAdapter;

    private LinkedList<ChatMessage> messages = new LinkedList<ChatMessage>();

    public void onCustomCreateView(LayoutInflater inflater) {
        fragmentActivity.hideTabBar();
        Session session = Session.newSession();
        userGuid = (String) session.get("userGuid");

        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragmentActivity.showTabBar();
                webSocketClient.close();
                onBackPressed();
            }
        });

        inviteButton = (ImageButton) mainView.findViewById(R.id.invite_btn);

        inviteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        JSONObject paramJson = new JSONObject();
                        try {
                            paramJson.put("guid", userGuid);
                            StringEntity paramEntity = new StringEntity(paramJson.toString(), Constant.CHARSET_UTF8);
                            String result = ServerAccessHelper.queryStringForPost(RemoteUrlCollections.getUrl(UrlSuffix.FRIENDS_JOINREQUEST_REQUEST), token.getToken(), paramEntity);
                            if (!Constant.RESPONSE_BADLY.equals(result)) {
                                getActivity().runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(getActivity(), getString(R.string.invite_send), Toast.LENGTH_SHORT).show();
                                        inviteButton.setVisibility(View.GONE);
                                    }
                                });

                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });

        messageEditText = (EditText) mainView.findViewById(R.id.message_input_box);

        messageEditText.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_ENTER) {
                        String message = messageEditText.getText().toString();
                        if (StringUtils.hasText(message)) {
                            sendMessage(message);
                        }
                    }
                }
                return false;
            }
        });

        messagesView = (ListView) mainView.findViewById(R.id.chat_messages_list);
        messageAdapter = new ChatMessageAdapter(fragmentActivity);
        messagesView.setAdapter(messageAdapter);
    }

    private void sendMessage(final String message) {
        InputMethodManager imm = (InputMethodManager) mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = RemoteUrlCollections.getUrl(UrlSuffix.SEND_MESSAGE);
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("guid", userGuid);
                    jsonObject.put("message", message);
                    jsonObject.put("group", false);
                    StringEntity paramEntity = new StringEntity(jsonObject.toString(), Constant.CHARSET_UTF8);
                    final String response = ServerAccessHelper.queryStringForPost(url, token.getToken(), paramEntity);
                    if(!Constant.RESPONSE_BADLY.equals(response)){
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                messageEditText.setText("");
                                ChatMessage chatMessage = convertToChatMessage(response);
                                messages.addFirst(chatMessage);
                                dbManager.cacheChatMessage(userGuid, response);
                                messageAdapter.notifyDataSetChanged();
                            }
                        });
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public int getViewId() {
        return R.layout.user_information;
    }

    @Override
    public int getSourceId() {
        return R.id.user_info;
    }

    @Override
    public void updateUI() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                userInfo = ServerAccessHelper.loadUserInfo(userGuid, token.getToken());
                getActivity().runOnUiThread(uiUserInfoUpdate);
            }
        }).start();

    }

    private Runnable uiUserInfoUpdate = new Runnable() {
        @Override
        public void run() {
            if (userInfo != null) {
                renderUserInfo(userInfo);
            }
        }
    };

    private void renderUserInfo(UserInfo userInfo) {
        boolean isFriend = userInfo.isFriend();
        if (isFriend) {
            addWebSocket();
            loadMessage();
        }

        ImageView photoView = (ImageView) mainView.findViewById(R.id.user_photo);
        loadUserImage(userInfo.getGuid(), photoView);

        HuaWenHuPoTextView usernameView = (HuaWenHuPoTextView) mainView.findViewById(R.id.username);
        usernameView.setText(userInfo.getNickname(token.getGuid()));

        Location location = userInfo.getLocation();
        UserToken userToken = dbManager.retrieveCurrentUser();
        HuaWenHuPoTextView locationView = (HuaWenHuPoTextView) mainView.findViewById(R.id.location);
        String latitude = location.getLatitude();
        String longitude = location.getLongitude();
        String latitude1 = userToken.getLatitude();
        String longitude1 = userToken.getLongitude();
        if (StringUtils.hasText(latitude) && StringUtils.hasText(longitude) && StringUtils.hasText(latitude1) && StringUtils.hasText(longitude1)) {
            double gps2m = LocationUtils.gps2m(Double.valueOf(latitude), Double.valueOf(longitude), Double.valueOf(latitude1), Double.valueOf(longitude1));
            int locationAsM = Integer.parseInt(new java.text.DecimalFormat("0").format(gps2m));
            locationView.setText(getString(R.string.distance_with_you) + locationAsM + getString(R.string.m));
        } else {
            locationView.setText(getString(R.string.no_distance_information));
        }

        if (!userInfo.isFriend() && !userInfo.getGuid().equals(token.getGuid())) {
            inviteButton.setVisibility(View.VISIBLE);
        }
    }

    private void loadMessage() {
        List<String> messagesAsJSONString = dbManager.retrieveChatMessage(userGuid);
        final List<ChatMessage> localStorageMessage = new ArrayList<ChatMessage>();
        for (String messageAsString : messagesAsJSONString) {
            ChatMessage chatMessage = convertToChatMessage(messageAsString);
            localStorageMessage.add(chatMessage);
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                final String userGuid = userInfo.getGuid();
                String url = RemoteUrlCollections.getUrl(UrlSuffix.MESSAGES) + "?identifier=" + userGuid;
                final String result = ServerAccessHelper.queryStringForGet(url, token.getToken());
                if (!Constant.RESPONSE_BADLY.equals(result)) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                JSONArray jsonArray = new JSONArray(result);
                                for (int i = 0; i < jsonArray.length(); i++) {
                                    String jsonAsString = jsonArray.getString(i);
                                    dbManager.cacheChatMessage(userGuid, jsonAsString);
                                    ChatMessage chatMessage = convertToChatMessage(jsonAsString);
                                    messages.add(chatMessage);
                                }
                                messages.addAll(localStorageMessage);
                                messageAdapter.notifyDataSetChanged();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        }).start();
    }

    private ChatMessage convertToChatMessage(String jsonAsString) {
        try {
            JSONObject messageJSONObject = new JSONObject(jsonAsString);
            String guid = messageJSONObject.getString("guid");
            String senderGuid = messageJSONObject.getString("sender");
            String message = messageJSONObject.getString("message");
            String datetime = messageJSONObject.getString("time");
            return new ChatMessage(guid, senderGuid, message, datetime);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void addWebSocket() {
        try {
            String currentUserGuid = token.getGuid();
            String path = "/message/chat?friendGuid=" + userGuid + "&currentUserGuid=" + currentUserGuid;
            URI uri = new URI(RemoteUrlCollections.WEB_SOCKET_HOST + path);
            webSocketClient = new ChatMessageWebSocket(uri, new Draft_17());
            webSocketClient.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private class ChatMessageWebSocket extends WebSocketClient {
        public ChatMessageWebSocket(URI serverURI) {
            super(serverURI);
        }

        public ChatMessageWebSocket(URI serverUri, Draft draft) {
            super(serverUri, draft);
        }

        public ChatMessageWebSocket(URI serverUri, Draft draft, Map<String, String> headers, int connecttimeout) {
            super(serverUri, draft, headers, connecttimeout);
        }

        @Override
        public void onOpen(ServerHandshake serverHandshake) {
            Log.d("WebSocket", "Web socket on open");
        }

        @Override
        public void onMessage(final String s) {
            Log.d("WebSocket", "Web socket on message [" + s + "]");
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        dbManager.cacheChatMessage(userGuid, s);
                        JSONObject jsonObject = new JSONObject(s);
                        String guid = jsonObject.getString("guid");
                        String senderGuid = jsonObject.getString("sender");
                        String message = jsonObject.getString("message");
                        String datetime = jsonObject.getString("time");
                        messages.addFirst(new ChatMessage(guid, senderGuid, message, datetime));
                        messageAdapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        @Override
        public void onClose(int i, String s, boolean b) {
            Log.d("WebSocket", "Web socket on close");
        }

        @Override
        public void onError(Exception e) {
            Log.e("WebSocket", "Web socket on error [" + e + "]");
        }
    }

    private class ChatMessageAdapter extends BaseAdapter {
        private LayoutInflater inflater;//布局填充器,可以使用xml文件来生成它的view对象

        public ChatMessageAdapter(MainTabsActivity context) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return messages.size();
        }

        @Override
        public Object getItem(int position) {
            return messages.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ChatMessage chatMessage = messages.get(position);
            ImageView avatarView;
            if (chatMessage.senderIsMe(token.getGuid())) {
                convertView = inflater.inflate(R.layout.me_message_item, null);
            } else {
                convertView = inflater.inflate(R.layout.friend_message_item, null);
            }
            avatarView = (ImageView) convertView.findViewById(R.id.user_photo);
            loadUserImage(chatMessage.getSenderGuid(), avatarView);

            TextView messageView = (TextView) convertView.findViewById(R.id.message);
            TextView datetimeView = (TextView) convertView.findViewById(R.id.datetime);

            messageView.setText(chatMessage.getMessage());
            datetimeView.setText(chatMessage.getDatetime());
            return convertView;
        }
    }

}
